Guided tutorial

The simplest way to use scigenex is to run the following steps using the Seurat R package:

  • Load data into a Seurat object
  • Perform quality Control
  • Perform normalization

The subsequent object can be used as input to SciGeneX. Alternatively, you can provide a normalized matrix as input.

The dataset

For this tutorial, we will use scRNA-seq dataset of Peripheral Blood Mononuclear Cells (PBMC) freely available on 10x Genomics web site. This dataset contains 2700 single cells sequenced on the Illumina NextSeq 500. This dataset can be downloaded from 10X Genomics or through the SeuratDatalibrary

Preparing the pbmc3k dataset

In this step, we will run the classical pre-processing steps from the. Please refer to this tutorial for more informations. If you have already pre-processed your data with Seurat or have a normalized count matrix as input, you can skip this step.

We next runthe classical steps of the seurat pipeline. For more information, you can check Seurat website here.

# Quality control
pbmc3k[["percent.mt"]] <- PercentageFeatureSet(pbmc3k, pattern = "^MT-")
pbmc3k <- subset(pbmc3k, subset = percent.mt < 5 & nFeature_RNA > 200)

# Normalizing
pbmc3k <- NormalizeData(pbmc3k)

# Identification of highly variable genes
pbmc3k <- FindVariableFeatures(pbmc3k, selection.method = "vst", nfeatures = 2000)

# Scaling data
pbmc3k <- ScaleData(pbmc3k, features = rownames(pbmc3k), verbose = FALSE)

# Perform principal component analysis
pbmc3k <- RunPCA(pbmc3k, features = VariableFeatures(object = pbmc3k), verbose = FALSE)

# Cell clustering 
pbmc3k <- FindNeighbors(pbmc3k, dims = 1:10, verbose = FALSE)
pbmc3k <- FindClusters(pbmc3k, resolution = 0.5, verbose = FALSE)

# Dimension reduction
pbmc3k <-suppressWarnings(RunUMAP(pbmc3k, dims = 1:10, verbose = FALSE))
DimPlot(pbmc3k, reduction = "umap")

Extracting gene modules using SciGeneX

In this section, we use the previously generated Seurat object as an input to run SciGeneX main commands. This command run the main algorithm that will:

  • Identify and extracts co-expressed genes
  • Partition selected genes into clusters
  • Store the result in a ClusterSet object

First we will load the Scigenex library. To limit the verbosity of Scigenex function we will set the verbosity level to zero (which will switch off information messages and debugging messages).

Then we call successively the select_genes() function which will select informative genes (i.e co-regulated), then the gene_clustering() function which will call MCL and partition the dataset into gene modules.

# Select informative genes
pbmc_scigenex <- select_genes(pbmc3k,
                              k = 80,
                              distance_method = "pearson",
                              which_slot = "data",
                              row_sum=2)

# Run MCL
pbmc_scigenex <- gene_clustering(pbmc_scigenex,
                                 k = 5,
                                 threads = 2,
                                 inflation = 2)

The object produced is a ClusterSet objet that is a S4 object that is intented to store gene modules.

isS4(pbmc_scigenex)
## [1] TRUE
pbmc_scigenex
##      An object of class ClusterSet
##      Name: s8gZ5uYQ33 
##      Memory used:  97239768 
##      Number of cells:  2643 
##      Number of informative genes:  2266 
##      Number of gene clusters:  232 
##      This object contains the following informations:
##           -  data 
##           -  gene_clusters 
##           -  top_genes 
##           -  gene_clusters_metadata 
##           -  gene_cluster_annotations 
##           -  cells_metadata 
##           -  dbf_output 
##           -  parameters 
##               *  distance_method  =  pearson 
##               *  k  =  80 
##               *  noise_level  =  5e-05 
##               *  fdr  =  0.005 
##               *  row_sum  =  2 
##               *  no_dknn_filter  =  FALSE 
##               *  seed  =  123 
##               *  keep_nn  =  FALSE 
##               *  k_mcl_graph  =  5 
##               *  output_path  =  /var/folders/zy/wl3dj2_n76zfc8sdvny1q06c0000gn/T//RtmpNqEch3 
##               *  name  =  s8gZ5uYQ33 
##               *  inflation  =  2

There are various methods associated with the ClusterSet objects.

##  [1] "["                        "%in%"                    
##  [3] "clust_names"              "clust_size"              
##  [5] "cluster_set_to_xls"       "cluster_stats"           
##  [7] "col_names"                "dim"                     
##  [9] "enrich_go"                "gene_cluster"            
## [11] "grep_clust"               "nclust"                  
## [13] "plot_clust_enrichments"   "plot_ggheatmap"          
## [15] "plot_markers_to_clusters" "rename_clust"            
## [17] "reorder_clust"            "reorder_genes"           
## [19] "row_names"                "show"                    
## [21] "top_by_go"                "top_genes"               
## [23] "viz_enrich"               "which_clust"

The current object contains 2266 informative genes, 2643 samples and 232 gene modules.

nrow(pbmc_scigenex)
## [1] 2266
ncol(pbmc_scigenex)
## [1] 2643
nclust(pbmc_scigenex)
## [1] 232

At this step, several modules need to be filtered out as lots of them may be singletons. Interestingly, the ClusterSet class implements the indexing operator/function (“[”). The first argument/dimension of the indexing function corresponds to the cluster stored in the object. The second dimension correspond to cell names. As an example, one can simply keep gene modules with size (i.e number of genes) greater than 7 using the following code. This leads to an object containing 48 gene modules.

pbmc_scigenex <- pbmc_scigenex[clust_size(pbmc_scigenex) > 7, ]
nclust(pbmc_scigenex)
## [1] 48

It may also be important to filter out gene based on dispersion. Several parameters can be computed for each cluster using the cluster_stats()function.

plot_cluster_stats(cluster_stats(pbmc_scigenex)) + 
 ggplot2::theme(axis.text.y = ggplot2::element_blank(),
                axis.text.x = element_text(angle=45, vjust = 0.5),
                panel.grid = element_blank()) 

Here we will select gene modules based on standard deviation (> 0.1) and rename the cluster (from 1 to the number of clusters):

pbmc_scigenex <- pbmc_scigenex[cluster_stats(pbmc_scigenex)$sd_total > 0.1, ] 
pbmc_scigenex <- rename_clust(pbmc_scigenex)
nclust(pbmc_scigenex)
## [1] 17

The we check the statistics again.

plot_cluster_stats(cluster_stats(pbmc_scigenex)) + 
 ggplot2::theme(axis.text.y = ggplot2::element_blank(),
                axis.text.x = element_text(angle=45, vjust = 0.5),
                panel.grid = element_blank()) 

Clusters of genes are stored in the gene_clusters slot. One can access the gene names from a cluster using the get_genes() command. By default, all genes are returned.

# Extract gene names from the 5th gene cluster
genes_module_5 <- get_genes(pbmc_scigenex, cluster = 5)
head(genes_module_5)
## [1] "CD79A"     "MS4A1"     "CD79B"     "HLA-DQA1"  "TCL1A"     "LINC00926"

One can also access the gene to cluster mapping using get_genes().

head(gene_cluster(pbmc_scigenex))
##   CST3 TYROBP   AIF1   LST1    LYZ    FTL 
##      1      1      1      1      1      1
tail(gene_cluster(pbmc_scigenex))
##      SDCBP2 RP4-781K5.2    C1orf198       SSFA2       ZGLP1        WBP5 
##          17          17          17          17          17          17

Visualisation using heatmap

Visualization of specific gene modules

The visualization of a heatmap containing all cells and modules may be time consuming and may require important memory ressources. A first alternative is to look at gene cluster individually or a subset of clusters. The gene modules can be visualized using the plot_heatmap() or the plot_ggheatmap() functions. The first is mainly intented to propose interactive vizualisation based on the iheatmapr library and allows to easily browse the results and zoom on particular regions of the heatmap The second should be mostly used for non interactive vizualisation. This second solution leads to a plot that is more easilly customable as it is bas ed on the ggplot framework. Here we use plot_ggheatmap() to have a look at the 4 first clusters. Note that here, we choose to order columns/cells on Seurat::FindClusters results.

plot_ggheatmap(pbmc_scigenex[1:4, ], 
               use_top_genes = FALSE,
               ident=Idents(pbmc3k)) + ggtitle("Cluster 1") 

Heatmap of representative genes

However one alternative is to extract the most representative genes of each cluster. This can be achieved using the top_genes() function. This function will store the identifiers of these representative genes inside the top_genes slot of the ClusterSet object. The top_genesslot can be accessed the get_genes() function.

pbmc_scigenex <- top_genes(pbmc_scigenex)
genes_cl5_top <- get_genes(pbmc_scigenex, cluster = 5, top = TRUE)
genes_cl5_top
##  [1] "CD79A"     "MS4A1"     "HLA-DQA1"  "CD79B"     "HLA-DQB1"  "TCL1A"    
##  [7] "LINC00926" "VPREB3"    "HLA-DQA2"  "FCER2"     "BANK1"     "TSPAN13"  
## [13] "HLA-DOB"   "FCRLA"     "HVCN1"     "CD37"      "PKIG"      "GNG7"     
## [19] "EAF2"      "SPIB"

Both plot_heatmap() and plot_ggheatmap() support the use_top_genesargument:

plot_ggheatmap(pbmc_scigenex, 
               use_top_genes = TRUE,
               ident=Seurat::Idents(pbmc3k)) + ggtitle("All clusters (top genes)") +
               theme(strip.text.y = element_text(size=4))

Interactive heatmap

A very interesting feature of Scigenex is its ability to display gene expression levels across cells through interactive heatmaps. Using this feature, user can interactively assess the expression levels in selected cells or cluster or on the whole dataset. However, it is generally advisable, when using all the clusters to restrict analysis using top_genes=TRUE. Here we will display the expression levels across cells of cluster 3 to 5.

plot_heatmap(pbmc_scigenex[3:5, ], 
               use_top_genes = TRUE,
               cell_clusters =Seurat::Idents(pbmc3k))

Exporting modules

Gene modules can be exported using the cluster_set_to_xls(). This function will create a Excel workbook that will contain the mapping from genes to modules.

tmp_file <- file.path(tempdir(), "pbmc_scigenex_out.xls")
cluster_set_to_xls(object=pbmc_scigenex, file_path=tmp_file)

Functional enrichment analysis

Functional enrichment analysis can be performed for each gene module using the enrich_go() function. Enrichments can be displayed using the plot_clust_enrichments() function.

# Functional enrichment analysis
pbmc_scigenex <- enrich_go(pbmc_scigenex, specie = "Hsapiens", ontology = "BP")
plot_clust_enrichments(pbmc_scigenex, gradient_palette=colors_for_gradient("Je1"), 
                       floor=50,
                       nb_go_term = 2) + 
  theme(axis.text.y = element_text(size=4))

Mapping cell populations markers onto the gene modules

Given a set of markers, the plot_markers_to_clusters() function can be used to map cell type markers to gene modules. This function will display jaccard and hypergeometric statistics. Here we will use the markers from the sctype.app database.

sctype <- "https://zenodo.org/record/8269433/files/sctype.app.tsv"
marker_table <- read.table(sctype, head=TRUE, sep="\t")
marker_table <- marker_table %>% 
                filter(Tissue == "Immune system") %>% 
                filter(!grepl('Pro-|Pre-|HSC|precursor|Progenitor', Cell.type)) %>%
                separate_rows(Marker_genes, convert = TRUE)

markers <- split(marker_table$Marker_genes, 
                 marker_table$Cell.type)
plot_markers_to_clusters(pbmc_scigenex, 
                         markers=markers, background = rownames(pbmc3k))

Working with spatial transcriptomics datasets

The scigenex package offers a certain number of function dedicated to spatial transcriptomic data analysis. At the moment these functions have been mainly developed to analyse VISIUM technology (10X Genomics).

Searching for gene modules

Pre-process spatial transcriptomics data

Here we will use the stxBrain dataset as example. This dataset is available from SeuratData library and contains mouse brain spatial expression over in several datasets. Two datasets are for the posterior region, two for the anterior. We will use the anterior1 dataset that we will first pre-process using Seurat.

#download.file("https://zenodo.org/record/8278514/files/brain1_gn.Rdata", 
#              destfile = "brain1_gn.Rdata", 
#              quiet = TRUE)
#load("brain1_gn.Rdata")
brain1 <- LoadData("stxBrain", type = "anterior1")
brain1 <- NormalizeData(brain1, 
                        normalization.method = "LogNormalize",
                        verbose = FALSE)
brain1 <- ScaleData(brain1, verbose = FALSE)
brain1 <- FindVariableFeatures(brain1, verbose = FALSE)
brain1 <- RunPCA(brain1, assay = "Spatial", verbose = FALSE)
brain1 <- FindNeighbors(brain1, reduction = "pca", dims = 1:20, verbose = FALSE)
brain1 <- FindClusters(brain1, verbose = FALSE)
brain1 <- RunUMAP(brain1, reduction = "pca", dims = 1:20, verbose = FALSE)

DimPlot(brain1, reduction = "umap", label = TRUE)

SpatialDimPlot(brain1, label = TRUE, label.size = 3, pt.size.factor = 1.4)
## Scale for fill is already present.
## Adding another scale for fill, which will replace the existing scale.

Calling scigenex

We will call scigenex and apply filtering on gene modules based on cluster size (min number of genes 7) and standard deviation (gene module sd > 0.1).

res_brain <- select_genes(data=brain1,
                    distance_method="pearson",
                    row_sum = 5)

gc_brain <- gene_clustering(res_brain, keep_nn = F, inflation = 2.2, threads = 4)
gcs_brain <- filter_cluster_size(gc_brain, min_cluster_size = 7)
df <- cluster_stats(gcs_brain) 
gcss_brain <- gcs_brain[df$sd_total > 0.1, ]
gcss_brain <- rename_clust(gcss_brain)
length(row_names(gcss_brain))
## [1] 2093
nclust(gcss_brain)
## [1] 26

Interestingly, Scigenex algorithm is able to retrieve nclust(gcss_brain) gene modules. This is most probably reminiscent of cell complexity but also of numerous molecular pathways that are differentially activated across the organ and unanticipated complexity.

Visualizing corresponding heatmap

We then may display the corresponding heatmap using plot_ggheatmap().

gcss_brain <- top_genes(gcss_brain)
plot_ggheatmap(gcss_brain, 
               use_top_genes = TRUE,
               ident=Idents(brain1)) + ggtitle("All clusters (top genes)") +
               theme(strip.text.y = element_text(size=3))

Interactive heatmap

Again, as in the context of scRNA-seq, we may also use the powerful plot_heatmap() fonction which allows interactive exploration of all or specific clusters. Here we look at cluster 6 to 9.

plot_heatmap(gcss_brain[6:9, ], 
             use_top_genes = TRUE, 
             cell_clusters = Seurat::Idents(brain1))
# Try selecting a subset of columns/rows
# The 'home' button can be used to reset
# the heatmap

Visualizing topological clusters

The scigenex library implements the plot_spatial() function to display topological information. In addition to the signal, specific regions can be highlighted using a hull that can be created using the display_hull() function. Here will also add a hull around seurat cluster 0 and 2. We will then display signal for “seurat_clusters” metadata.

hull_white <- display_hull(getFlippedTissueCoordinates(brain1),
                           ident = ifelse(Idents(brain1) %in% c(0, 2), 
                                          1, 0),
                           color = "white", 
                           size_x=4, size_y=3, 
                           hull_type = "wall", 
                           size = 0.5, 
                           step_x = 2.6, 
                           step_y=2.4, 
                           delta = 1.5)

plot_spatial(seurat_obj = brain1, 
             metadata = "seurat_clusters", 
             pt_size=2.5, coord_flip = T) + hull_white

We may also want to visualize a specific gene. Here we will look at the pattern of “Hpca” which is part of the cluster 7 detected by Scigenex.

"Hpca" %in% gcss_brain
## [1] TRUE
Hpca_clust <- which_clust( gcss_brain, "Hpca")
Hpca_clust
## Hpca 
##    7

To this aim we will use the plot_spatial() function.

plot_spatial(seurat_obj = brain1, 
             gene_name = "Hpca",  
             pt_size=2.5, coord_flip = T) + hull_white  +
  ggtitle("Hpca expression pattern.")

Note that cluster 7 also contains several genes related to Regulator Of G Protein family and Potassium Channel Tetramerization Domain. This can be checked with a regular expression using the grep_clust() function:

grep_clust(gcss_brain[Hpca_clust, ], "(Rgs)|(Kctd)",)
## $`7`
## [1] "Rgs4"   "Rgs7bp" "Kctd17" "Kctd1"  "Rgs14"

To visualize the topological distribution of signals in each cluster we will (i) extract the gene_clusters slot from the gcss object, (ii) compute module score using the Seurat AddModuleScore()function and (iii) store the results in the seurat object. Note that, for each gene module, signal will be scaled from 0 to 1. This will allow us to have a shared legend between all plots

brain1 <- AddModuleScore(brain1, features = gcss_brain@gene_clusters)

for(i in 1:nclust(gcss_brain)){ # Normalizing module scores
  tmp <- brain1[[paste0("Cluster", i, sep="")]] 
  max_tmp <- max(tmp)
  min_tmp <- min(tmp)
  brain1[[paste0("Cluster", i, sep="")]]  <- (tmp[,1] - min(tmp))/(max_tmp - min_tmp)
}

The topological profile of cluster 7 (that contains Hpca, a strong hippocampus marker) is the following:

plot_spatial(seurat_obj = brain1, 
             metadata = paste("Cluster", setNames(Hpca_clust, NULL), 
                                         sep=""), 
             pt_size=2.5, coord_flip = T) + hull_white

We can easily see that the pattern of the gene module containing Hpca is very similar to the Hpca pattern. Moreover this gene module pattern also strongly overlaps the Seurat cell cluster number 0. However, the analysis seems to indicate that a more complex tissue architecture exists as Hpca signal extends beyond Seurat cluster 0.

We will then display the topological signal of all clusters using the plot_spatial_panel() function.

p <- plot_spatial_panel(brain1, 
                        metadata = paste("Cluster", 1:nclust(gcss_brain), 
                                         sep=""), 
                   ncol_layout = 3, 
                   pt_size=0.7, 
                   guide='collect',
                   stroke = 0, size_title = 5, 
                   face_title = 'plain', 
                   barwidth = 0.25, barheight = 1.5, 
                   coord_flip=T) 
print(p + guide_area())

Session info

## R version 4.2.2 (2022-10-31)
## Platform: x86_64-apple-darwin17.0 (64-bit)
## Running under: macOS Big Sur ... 10.16
## 
## Matrix products: default
## BLAS:   /Library/Frameworks/R.framework/Versions/4.2/Resources/lib/libRblas.0.dylib
## LAPACK: /Library/Frameworks/R.framework/Versions/4.2/Resources/lib/libRlapack.dylib
## 
## locale:
## [1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8
## 
## attached base packages:
## [1] stats     graphics  grDevices utils     datasets  methods   base     
## 
## other attached packages:
##  [1] tidyr_1.3.0                dplyr_1.1.2               
##  [3] scigenex_1.3.1             stxKidney.SeuratData_0.1.0
##  [5] stxBrain.SeuratData_0.1.1  pbmc3k.SeuratData_3.1.4   
##  [7] SeuratData_0.2.2           SeuratObject_4.1.3        
##  [9] Seurat_4.3.0               patchwork_1.1.2           
## [11] ggplot2_3.4.3             
## 
## loaded via a namespace (and not attached):
##   [1] rappdirs_0.3.3         SparseM_1.81           scattermore_0.8       
##   [4] ragg_1.2.5             bit64_4.0.5            knitr_1.43            
##   [7] irlba_2.3.5.1          data.table_1.14.8      KEGGREST_1.38.0       
##  [10] RCurl_1.98-1.10        generics_0.1.3         BiocGenerics_0.44.0   
##  [13] org.Mm.eg.db_3.16.0    cowplot_1.1.1          RSQLite_2.2.20        
##  [16] shadowtext_0.1.2       RANN_2.6.1             future_1.31.0         
##  [19] bit_4.0.5              enrichplot_1.18.3      spatstat.data_3.0-0   
##  [22] xml2_1.3.3             httpuv_1.6.11          viridis_0.6.4         
##  [25] amap_0.8-19            xfun_0.40              rJava_1.0-6           
##  [28] hms_1.1.3              jquerylib_0.1.4        evaluate_0.21         
##  [31] promises_1.2.1         fansi_1.0.4            progress_1.2.2        
##  [34] dbplyr_2.3.2.9000      igraph_1.5.1           DBI_1.1.3             
##  [37] htmlwidgets_1.6.2      sparsesvd_0.2-2        spatstat.geom_3.0-6   
##  [40] stats4_4.2.2           purrr_1.0.2            ellipsis_0.3.2        
##  [43] biomaRt_2.54.1         deldir_1.0-6           vctrs_0.6.3           
##  [46] Biobase_2.58.0         ROCR_1.0-11            abind_1.4-5           
##  [49] cachem_1.0.8           withr_2.5.0            ggforce_0.4.1         
##  [52] HDO.db_0.99.1          ggh4x_0.2.4            progressr_0.13.0      
##  [55] sctransform_0.3.5      treeio_1.22.0          prettyunits_1.1.1     
##  [58] goftest_1.2-3          cluster_2.1.4          DOSE_3.24.2           
##  [61] ape_5.7-1              lazyeval_0.2.2         crayon_1.5.2          
##  [64] spatstat.explore_3.0-6 slam_0.1-50            pkgconfig_2.0.3       
##  [67] labeling_0.4.2         tweenr_2.0.2           GenomeInfoDb_1.34.9   
##  [70] nlme_3.1-160           rlang_1.1.1            globals_0.16.2        
##  [73] lifecycle_1.0.3        miniUI_0.1.1.1         downloader_0.4        
##  [76] filelock_1.0.2         BiocFileCache_2.6.1    rprojroot_2.0.3       
##  [79] polyclip_1.10-4        matrixStats_0.63.0     lmtest_0.9-40         
##  [82] Matrix_1.5-4           aplot_0.1.9            zoo_1.8-11            
##  [85] pheatmap_1.0.12        ggridges_0.5.4         png_0.1-8             
##  [88] viridisLite_0.4.2      bitops_1.0-7           gson_0.0.9            
##  [91] KernSmooth_2.23-20     Biostrings_2.66.0      blob_1.2.3            
##  [94] stringr_1.5.0          qvalue_2.30.0          parallelly_1.34.0     
##  [97] spatstat.random_3.1-3  gridGraphics_0.5-1     S4Vectors_0.36.1      
## [100] scales_1.2.1           memoise_2.0.1          magrittr_2.0.3        
## [103] plyr_1.8.8             ica_1.0-3              zlibbioc_1.44.0       
## [106] compiler_4.2.2         scatterpie_0.1.8       RColorBrewer_1.1-3    
## [109] fitdistrplus_1.1-8     ggstar_1.0.4           cli_3.6.1             
## [112] XVector_0.38.0         listenv_0.9.0          pbapply_1.7-0         
## [115] MASS_7.3-58.1          tidyselect_1.2.0       stringi_1.7.12        
## [118] textshaping_0.3.6      highr_0.10             yaml_2.3.7            
## [121] GOSemSim_2.24.0        ggrepel_0.9.3          grid_4.2.2            
## [124] sass_0.4.7             fastmatch_1.1-3        tools_4.2.2           
## [127] future.apply_1.10.0    parallel_4.2.2         rstudioapi_0.15.0     
## [130] gridExtra_2.3          farver_2.1.1           Rtsne_0.16            
## [133] ggraph_2.1.0           digest_0.6.33          shiny_1.7.5           
## [136] qlcMatrix_0.9.7        Rcpp_1.0.11            xlsx_0.6.5            
## [139] later_1.3.1            RcppAnnoy_0.0.20       org.Hs.eg.db_3.16.0   
## [142] httr_1.4.4             AnnotationDbi_1.60.0   colorspace_2.1-0      
## [145] brio_1.1.3             XML_3.99-0.13          fs_1.6.3              
## [148] tensor_1.5             reticulate_1.28        IRanges_2.32.0        
## [151] splines_4.2.2          uwot_0.1.14            yulab.utils_0.0.6     
## [154] tidytree_0.4.2         spatstat.utils_3.0-1   pkgdown_2.0.7         
## [157] graphlayouts_0.8.4     xlsxjars_0.6.1         sp_1.6-0              
## [160] ggplotify_0.1.0        plotly_4.10.1          systemfonts_1.0.4     
## [163] xtable_1.8-4           jsonlite_1.8.7         ggtree_3.6.2          
## [166] dynamicTreeCut_1.63-1  tidygraph_1.2.3        iheatmapr_0.5.1       
## [169] testthat_3.1.6         ggfun_0.0.9            R6_2.5.1              
## [172] pillar_1.9.0           htmltools_0.5.6        mime_0.12             
## [175] glue_1.6.2             fastmap_1.1.1          clusterProfiler_4.6.0 
## [178] BiocParallel_1.32.5    codetools_0.2-18       fgsea_1.24.0          
## [181] utf8_1.2.3             lattice_0.20-45        bslib_0.5.1           
## [184] spatstat.sparse_3.0-0  tibble_3.2.1           curl_5.0.0            
## [187] leiden_0.4.3           GO.db_3.16.0           survival_3.4-0        
## [190] docopt_0.7.1           rmarkdown_2.24         desc_1.4.2            
## [193] munsell_0.5.0          fastcluster_1.2.3      GenomeInfoDbData_1.2.9
## [196] reshape2_1.4.4         gtable_0.3.3